#include "stdafx.h"
#include "JsFunction.h"
#include <assert.h>
#include "Cpu.h"
#include "CheckRegister.h"


JsFunction::~JsFunction()
{
    if (convertedStr.length())
    {
        JsFunctionManager::_instance->_remove(JsFunctionManager::idFromFunctionStr(convertedStr));
    }
    convertedStr.clear();
}


JsFunctionManager::JsFunctionManager()
{
    assert(_instance == nullptr);
    _instance = this;
}


JsFunctionManager::~JsFunctionManager()
{
}

void JsFunctionManager::init(Cpu *cpu)
{
    CHECK_REGISTER();
    assert(_instance == nullptr);
    _instance = new JsFunctionManager;

    cpu->setOn("serverFunctionCalled", _instance, &JsFunctionManager::onJsFunctionCalled);
}

JsFunction JsFunctionManager::port(JsFunctionType func)
{
    auto index = _instance->_add(func);

    return mkJsFunctionStr(index);
}

QString JsFunctionManager::mkJsFunctionStr(uint64_t id)
{
    return QString("ServerJsFunctionWarpper:%1").arg(id);
}

uint64_t JsFunctionManager::idFromFunctionStr(const QString str)
{
    return str.mid(24).toULongLong();
}

uint64_t JsFunctionManager::_add(JsFunctionType func)
{
    std::lock_guard<std::mutex> guard(locker);
    functions.emplace(lastId, func);
    return lastId++;
}

void JsFunctionManager::_remove(uint64_t id)
{
    std::lock_guard<std::mutex> guard(locker);
    functions.erase(id);
}

void JsFunctionManager::onJsFunctionCalled(QVariantMap args)
{
    uint64_t id = args.value("id").toULongLong();
    QVariant fnargs = args.value("args");
    functions.at(id)(fnargs);
}

JsFunctionManager * JsFunctionManager::_instance = nullptr;
